XBinder™
XML到代码生成工具
高效、低成本的XML数据绑定和代码生成XML加快了项目的上市时间XBinder的特性现在包括了:
1. 组在XML Schema 1.1中包含重复元素和通配符的能力为什么要使用XML数据绑定或XML代码生成工具?
与传统XML API(如SAX和DOM)相比,XBinder的XML数据绑定具有以下优点:XBinder的概述
XBinder是C/C++、Java或C#代码生成工具的XML模式。XML数据绑定(或代码生成)是将XML模式信息项转换为计算机语言中的类型定义和函数的过程。对比
假设您需要编写代码来解析下面的XML实例,并打印出其中包含的所有数据。
<purchase>
<customer number="12345">
John Smith
</customer>
<store>
Toys R Us
</store>
<item>
Toy Bath Set
</item>
<price>
19.95
</price>
</purchase>
在这个页面上,我们将比较在没有XBinder的情况下解析这个实例所需的代码量与使用XBinder进行解析所需的代码量。这两个例子都将使用C++。对于非XBinder代码,我们将使用libxml++的DOM功能。
下面是不使用XBinder时需要编写的代码:
#include <libxml++/libxml++.h>
#include <stdio.h>
int main()
{
// Parse the XML file.
xmlpp::DomParser parser;
parser.set_substitute_entities();
try
{
parser.parse_file("purchase.xml");
}
catch (std::exception& ex)
{
printf("\n%s", ex.what());
}
// Get the root node.
xmlpp::Node* pPurchaseNode = parser.get_document()->get_root_node();
Glib::ustring nodename = pPurchaseNode->get_name();
// Get the root node's children in a list.
xmlpp::Node::NodeList purchaseChildren = pPurchaseNode->get_children();
// Now walk through the children and process them according to what element
// is represented.
for (xmlpp::Node::NodeList::iterator iter = purchaseChildren.begin();
iter != purchaseChildren.end(); ++iter)
{
xmlpp::Node* pChildNode = *iter;
nodename = pChildNode->get_name();
if (nodename == "text")
{
// We'll get the text value for each element explicitly
// as we encounter them.
continue;
}
else if (nodename == "customer")
{
// We're at the <customer> node. We want to print the customer
// name and number.
xmlpp::Element* pChildElement =
dynamic_cast<xmlpp::Element*> (pChildNode);
xmlpp::Attribute* pCustomerAttr =
pChildElement->get_attribute("number");
printf("\nCustomer number: %s", pCustomerAttr->get_value().c_str());
xmlpp::TextNode* pChildText = pChildElement->get_child_text();
printf("\nCustomer name: %s", pChildText->get_content().c_str());
}
else if (nodename == "store")
{
// We're at the <store> node. We want to print the store name.
xmlpp::Element* pChildElement =
dynamic_cast<xmlpp::Element*> (pChildNode);
xmlpp::TextNode* pChildText = pChildElement->get_child_text();
printf("\nStore name: %s", pChildText->get_content().c_str());
}
else if (nodename == "item")
{
// We're at the <item> node. We want to print the item name.
xmlpp::Element* pChildElement =
dynamic_cast<xmlpp::Element*> (pChildNode);
xmlpp::TextNode* pChildText = pChildElement->get_child_text();
printf("\nItem name: %s", pChildText->get_content().c_str());
}
else if (nodename == "price")
{
// We're at the <price> node. We want to print the price.
xmlpp::Element* pChildElement =
dynamic_cast<xmlpp::Element*> (pChildNode);
xmlpp::TextNode* pChildText = pChildElement->get_child_text();
printf("\nPrice: %s", pChildText->get_content().c_str());
}
}
return 0;
}
下面是需要使用XBinder编写的代码:
#include "rtxsrc/OSRTFileInputStream.h"
#include "rtxmlsrc/rtXmlCppMsgBuf.h"
#include <Purchase.h>
#include <stdio.h>
int main()
{
// Setup to decode the instance in purchase.xml
int stat;
const char* filename = "Purchase.xml";
OSRTFileInputStream in (filename);
OSXMLDecodeBuffer decodeBuffer (in);
purchase_CC pdu (decodeBuffer);
// Do the decode
stat = pdu.decode();
// Print the information that was in the instance.
PurchaseRecord* pPurchase = pdu.getValue();
printf("\nCustomer number: %d", pPurchase->customer.number);
printf("\nCustomer name: %s", pPurchase->customer.value.c_str());
printf("\nStore name: %s", pPurchase->store.c_str());
PurchaseRecord_3* pItemAndPrice = pPurchase->_seq3.getItem(0);
unsigned short i = 0;
while (pItemAndPrice != 0)
{
printf("\nItem name: %s", pItemAndPrice->item.c_str());
printf("\nItem price: %.2f", pItemAndPrice->price);
pItemAndPrice = pPurchase->_seq3.getItem(++i);
}
return stat;
}
关于这些代码示例,有几点值得注意: